/***********************************************************************************
 * 文件名： soft_capture.c
 * 版本： 3
 * 说明：
 * 		利用IO中断和定时器，软件模拟硬件捕获输入组件。
 * 		可用于外部电平变化时间的检测。
 *      关键函数为 SoftCT_EvIOInt 函数，确保最高优先级响应，不被其他中断打断。
 *      在文件 soft_capture_config.h 进行正确的配置。
 * 修改记录：
 * 	2022/02/10: 初版。 黄均铭。
 *  2022/02/18：修复中断中不严谨的BUG
 *  2022/03/07：添加定时器查询模式
 ***********************************************************************************/
#include "soft_capture.h"
#include "..\..\polsys.h"

volatile softct_value_t SoftCT_mCaptureValue;
static volatile softct_event_t mCaptureEvent;

#ifdef _SOFTCT_USE_EVENT_NOTIFICATION
// 外部实现事件通知函数
void SoftCT_Event(softct_event_t e);
#endif

// IO口中断事件
void SoftCT_EvIOInt()
{
    if (mCaptureEvent == SOFTCT_EVENT_NULL)
    {
        SoftCT_mCaptureValue = _SoftCT_TimGetCount();
        _SoftCT_TimStop();
        _SoftCT_ExitCritical();
#if _SOFTCT_INT_CONSUMPTION > 0
        // 执行消耗
        if (SoftCT_mCaptureValue >= _SOFTCT_INT_CONSUMPTION)
        {
            SoftCT_mCaptureValue -= _SOFTCT_INT_CONSUMPTION;
        }
#endif
        // 防止响应中断过程中溢出，做一个判断
        if (_SoftCT_TimGetOvfFlag())
        {
            // 溢出事件
            mCaptureEvent = SOFTCT_EVENT_OVF;
        }
        else
        {
            // 捕获事件
            mCaptureEvent = SOFTCT_EVENT_CMB;
        }
        // 事件通知
#ifdef _SOFTCT_USE_EVENT_NOTIFICATION
        SoftCT_Event(mCaptureEvent);
#endif
    }
}

#ifndef _SOFTCT_USE_TIMER_QUERY
// 定时器溢出
void SoftCT_EvTimeout()
{
    if (mCaptureEvent == SOFTCT_EVENT_NULL)
    {
        _SoftCT_TimStop();
        _SoftCT_ExitCritical();
        mCaptureEvent = SOFTCT_EVENT_OVF;
        // 事件通知
#ifdef _SOFTCT_USE_EVENT_NOTIFICATION
        SoftCT_Event(SOFTCT_EVENT_OVF);
#endif
    }
}
#endif

// 获取当前发生的事件
softct_event_t SoftCT_GetEvent()
{
#ifdef _SOFTCT_USE_TIMER_QUERY
    while (mCaptureEvent == SOFTCT_EVENT_NULL)
    {
        _SoftCT_ClrWdt();
        if (_SoftCT_TimGetOvfFlag())
        {
            _SoftCT_TimStop();
            _SoftCT_ExitCritical();
            mCaptureEvent = SOFTCT_EVENT_OVF;
            // 事件通知
    #ifdef _SOFTCT_USE_EVENT_NOTIFICATION
            SoftCT_Event(SOFTCT_EVENT_OVF);
    #endif
        }
    }
#endif
    return mCaptureEvent;
}

// 开始捕获
void SoftCT_Run()
{
    // 清除计数
    SoftCT_mCaptureValue = 0;
    _SoftCT_TimClrCount();
    // 清除状态
    mCaptureEvent = SOFTCT_EVENT_NULL;
    _SoftCT_TimClrOvfFlag();
    // 确保IO中断和定时器中断的高优先级
    _SoftCT_EnterCritical();
    // 开始捕获
    _SoftCT_TimRun();
}

// 停止捕获
void SoftCT_Stop()
{
    _SoftCT_TimStop();
    _SoftCT_ExitCritical();
}


